package org.tony.utils;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.tony.db.DbUtil;
import org.tony.entity.DataCusomizedEntry;
import org.tony.entity.SubmitData;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * 解析数据源提交上来的xml格式数据
 * @author tony
 *
 */
public class PareseSubmitDataUtils {
	

	/**
	 * 解析数据
	 * @param xml
	 * @return
	 * @throws Exception
	 */
	public static SubmitData parseData(String xml) throws Exception {
		Document doc = getDocument(xml);
		Element root = doc.getDocumentElement() ;
		if(root != null && root.hasChildNodes()) {
			SubmitData sb = new SubmitData() ;
			sb.setOp(root.getAttribute("op")) ;
			sb.setRelationId(root.getAttribute("relation_id"));
			sb.setRelationValue(root.getAttribute("rel_key")) ;
			
			NodeList childs = root.getChildNodes() ;
			for(int i=0;i<childs.getLength();i++) {
				Node cur = childs.item(i);
				if(cur.getNodeType() == Node.ELEMENT_NODE) {
					Element e = (Element) cur ;
					sb.getValues().put(e.getAttribute("name"), e.getAttribute("value")) ;
				}
			}
			return sb ;
		}
		return null ;
	}
	
	/**
	 * 生成插入语句
	 * @param data
	 * @param columns
	 * @param tableName
	 * @param pkName
	 * @return
	 */
	private static String generateInsertSql(SubmitData data,Map<String,String> columns,String tableName,String pkName) {
		StringBuffer sql = new StringBuffer();
		sql.append("insert into " ) ;
		sql.append(tableName) ;
		sql.append("(" +pkName) ;
		Map<String,String> values = data.getValues() ;
		StringBuffer value = new StringBuffer(" values('" + data.getRelationValue() + "'");
		for(Iterator<String> keyIter = values.keySet().iterator();keyIter.hasNext();) {
			String col = keyIter.next() ;
			if(!col.equalsIgnoreCase(pkName)) {
				String colType = columns.get(col.toUpperCase());
				sql.append(",") ;
				sql.append(col) ;
				value.append(",") ;
				if(DbUtil.TIME_STR.contains(colType.replaceAll("\\(\\d+\\)", ""))) {
					value.append("to_date('" + values.get(col) + "', 'yyyy/mm/dd hh24:mi:ss')") ;
				}else {
					value.append("'" + values.get(col) + "'") ;
				}
			}
		}
		sql.append(")") ;
		value.append(")");
		sql.append(value.toString()) ;
		return sql.toString() ;
	}
	
	/**
	 * 生成更新语句
	 * @param data
	 * @param columns
	 * @param tableName
	 * @param pkName
	 * @return
	 */
	private static String generateUpdateSql(SubmitData data,Map<String,String> columns,String tableName,String pkName) {
		
		StringBuilder upSql = new StringBuilder("update " + tableName +" set ");
		Map<String,String> values = data.getValues() ;
		for(Iterator<String> keyIter = values.keySet().iterator();keyIter.hasNext();) {
			String col = keyIter.next() ;
			String colType = columns.get(col.toUpperCase());
			upSql.append(col + "=") ;
			if(DbUtil.TIME_STR.contains(colType.replaceAll("\\(\\d+\\)", ""))) {
				upSql.append("to_date('" + values.get(col) + "', 'yyyy/mm/dd hh:mi:ss')") ;
			}else {
				upSql.append("'" + values.get(col) + "'") ;
			}
			
			if(keyIter.hasNext()) {
				upSql.append(",") ;
			}
		}
		
		upSql.append(" where "+ pkName +"='" + data.getRelationValue() + "'") ;
		return upSql.toString();
	}
	
	/**
	 * 生成sql语句
	 * @param sb
	 * @return
	 */
	public static String generateSql(SubmitData sb) {
		try {
			DataCusomizedEntry entry = DataCustomizedUtil.getInstance().search(sb.getRelationId()) ;
			Map<String,String> allColumns = DbUtil.getTableColumns(entry.getTableName(), JdbcHelper.system, true);
			if(sb.getOp().equals("insert")) {
				return generateInsertSql(sb, allColumns, entry.getTableName(), entry.getRelationKey()) ;
			}else if(sb.getOp().equals("update")) {
				return generateUpdateSql(sb, allColumns, entry.getTableName(), entry.getRelationKey()) ;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null ;
	}
	
	
	/**
	 * 根据xml字符串获取 xml文档
	 * @param xml
	 * @return
	 * @throws Exception
	 */
	private static Document getDocument(String xml) throws Exception {
		InputStream sis = new  ByteArrayInputStream(xml.getBytes(Charset.forName("UTF-8")));
		DocumentBuilderFactory docFac = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = docFac.newDocumentBuilder();
		Document doc = builder.parse(sis);
		sis.close() ;
		return doc;
		
	}
}
